#pragma once

/**
 * @file market_update.h
 * @brief 市场数据更新结构定义
 * @details 定义了匹配引擎和市场数据发布器使用的市场更新消息结构
 */

#include <sstream>

#include "common/types.h"
#include "common/lf_queue.h"

using namespace Common;

namespace Exchange {
  /**
   * @namespace Exchange
   * @brief 交易所相关功能的命名空间
   * @details 包含交易所、匹配引擎和市场数据发布等功能
   */
  /**
   * @brief 市场更新消息的类型/操作
   * @details 定义了市场数据更新的不同操作类型，如添加、修改、取消等
   */
  enum class MarketUpdateType : uint8_t {
    INVALID = 0,       /**< 无效的更新类型 */
    CLEAR = 1,         /**< 清除所有订单 */
    ADD = 2,           /**< 添加新订单 */
    MODIFY = 3,        /**< 修改现有订单 */
    CANCEL = 4,        /**< 取消现有订单 */
    TRADE = 5,         /**< 成交信息 */
    SNAPSHOT_START = 6, /**< 快照开始标记 */
    SNAPSHOT_END = 7   /**< 快照结束标记 */
  };

  /**
   * @brief 将市场更新类型转换为字符串
   * @param type 要转换的市场更新类型
   * @return 表示市场更新类型的字符串
   */
  inline std::string marketUpdateTypeToString(MarketUpdateType type) {
    switch (type) {
      case MarketUpdateType::CLEAR:
        return "CLEAR";
      case MarketUpdateType::ADD:
        return "ADD";
      case MarketUpdateType::MODIFY:
        return "MODIFY";
      case MarketUpdateType::CANCEL:
        return "CANCEL";
      case MarketUpdateType::TRADE:
        return "TRADE";
      case MarketUpdateType::SNAPSHOT_START:
        return "SNAPSHOT_START";
      case MarketUpdateType::SNAPSHOT_END:
        return "SNAPSHOT_END";
      case MarketUpdateType::INVALID:
        return "INVALID";
    }
    return "UNKNOWN";
  }

  /**
   * @brief 二进制结构打包指令
   * @details 这些结构会通过网络传输，因此二进制结构进行打包以移除系统相关的额外填充
   */
#pragma pack(push, 1)

  /**
   * @brief 匹配引擎内部使用的市场更新结构
   * @details 定义了匹配引擎内部处理的市场数据更新格式
   */
  struct MEMarketUpdate {
    /**
     * @brief 市场更新类型
     * @details 指示该更新的操作类型（添加、修改、取消等）
     */
    MarketUpdateType type_ = MarketUpdateType::INVALID;

    OrderId order_id_ = OrderId_INVALID;    /**< 订单ID */
    TickerId ticker_id_ = TickerId_INVALID; /**< 证券ID */
    Side side_ = Side::INVALID;             /**< 交易方向（买/卖） */
    Price price_ = Price_INVALID;           /**< 价格 */
    Qty qty_ = Qty_INVALID;                 /**< 数量 */
    Priority priority_ = Priority_INVALID;  /**< 优先级 */

    auto toString() const {
      std::stringstream ss;
      ss << "MEMarketUpdate"
         << " ["
         << " type:" << marketUpdateTypeToString(type_)
         << " ticker:" << tickerIdToString(ticker_id_)
         << " oid:" << orderIdToString(order_id_)
         << " side:" << sideToString(side_)
         << " qty:" << qtyToString(qty_)
         << " price:" << priceToString(price_)
         << " priority:" << priorityToString(priority_)
         << "]";
      return ss.str();
    }
  };

  /**
   * @brief 市场数据发布器通过网络发布的市场更新结构
   * @details 定义了市场数据发布器向外发布的市场数据更新格式，包含序列号
   */
  struct MDPMarketUpdate {
    /**
     * @brief 序列号
     * @details 标识市场数据更新的顺序号，用于确保数据完整性
     */
    size_t seq_num_ = 0;                 /**< 序列号 */
    MEMarketUpdate me_market_update_;      /**< 匹配引擎市场更新数据 */

    auto toString() const {
      std::stringstream ss;
      ss << "MDPMarketUpdate"
         << " ["
         << " seq:" << seq_num_
         << " " << me_market_update_.toString()
         << "]";
      return ss.str();
    }
  };

#pragma pack(pop) /**< 取消二进制结构打包指令 */

  /**
   * @brief 匹配引擎和市场数据发布器的无锁队列类型定义
   * @details 分别定义了用于匹配引擎市场更新消息和市场数据发布器市场更新消息的无锁队列类型
   */
  typedef Common::LFQueue<Exchange::MEMarketUpdate> MEMarketUpdateLFQueue;    /**< 匹配引擎市场更新消息的无锁队列类型 */
  typedef Common::LFQueue<Exchange::MDPMarketUpdate> MDPMarketUpdateLFQueue; /**< 市场数据发布器市场更新消息的无锁队列类型 */
}
